/**
 * 
 */
package com.security.frame.token.social;


import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.social.connect.UsersConnectionRepository;
import org.springframework.social.security.SocialUserDetailsService;
import org.springframework.util.CollectionUtils;

import java.util.HashSet;
import java.util.Set;

/**
 * 自定义短信Provider
 *
 * @author wangjie
 * @version V1.0
 * @date 2019/11/6
 */
@Slf4j
@Setter
@Getter
public class OpenIdAuthenticationProvider implements AuthenticationProvider {

	private SocialUserDetailsService userDetailsService;

	private UsersConnectionRepository usersConnectionRepository;

	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {

		OpenIdAuthenticationToken authenticationToken = (OpenIdAuthenticationToken ) authentication;

		Set<String> provideruserIds = new HashSet<>();
		provideruserIds.add((String) authenticationToken.getPrincipal());

        Set<String> userIdsConnectedTo = usersConnectionRepository.findUserIdsConnectedTo(authenticationToken.getProviderId(),provideruserIds);

        if(CollectionUtils.isEmpty(userIdsConnectedTo) || userIdsConnectedTo.size() != 1){
            throw  new InternalAuthenticationServiceException("无法获取用户信息");
        }

        String userId = userIdsConnectedTo.iterator().next();

        UserDetails user = userDetailsService.loadUserByUserId(userId);

		if (user == null) {
			log.info("【无法获取用户信息】");
			throw new InternalAuthenticationServiceException("无法获取用户信息");
		}
		
		OpenIdAuthenticationToken authenticationResult = new OpenIdAuthenticationToken(user, user.getAuthorities());
		
		authenticationResult.setDetails(authenticationToken.getDetails());

		return authenticationResult;
	}


	@Override
	public boolean supports(Class<?> authentication) {
		return OpenIdAuthenticationToken.class.isAssignableFrom(authentication);
	}

}
